#include "launcher.h"
#include "ui_launcher.h"

Launcher::Launcher(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Launcher)
{
    ui->setupUi(this);
    this->parsing_liste = new QRegularExpression("(fiche-anime-.*?)\".*?img src=\"(.*?)\".*?alt=\"(.*?)\"");
    this->parsing_anime = new QRegularExpression("textarea.*?synopsis\">(.*?)<",QRegularExpression::DotMatchesEverythingOption);    
    this->parsing_anime_infos = new QRegularExpression("<div class=\"bloc_contextuel\">.*?<ul style=\"clear: both; margin-bottom: 5px;\" class=\"bullet\">.*?<li><strong>Genre.*?</strong> (.*?)</li>.*?<li><strong>Année de parution :</strong> (.*?)</li>.*?<li><strong>Studio.*?</strong> (.*?)</li>.*?<li><strong>Épisodes réalisés :</strong> (.*?)</li>.*?<li><strong>Épisodes en ligne :</strong> (.*?)</li>.*?<li><strong>Subbé par :</strong> (.*?)</li>.*?<li><strong>Serveur :</strong> (.*?)</li>.*?</ul>",QRegularExpression::DotMatchesEverythingOption);
    this->parsing_episodes = new QRegularExpression("<tr class=\"download.*?\" id=\"(\\d+)\" >.*?<td class=\"cell\"><strong>(.*?)</strong></td><td class=\"cell\">(.*?)</td><td class=\"cell\">(.*?)</td><td class=\"cell\">(.*?)</td><td class=\"cell\">(.*?)</td><td class=\"cell\">(.*?)</td><td class=\"cell\">(.*?)</td>",QRegularExpression::DotMatchesEverythingOption);
    this->parsing_bonus = new QRegularExpression("<tr class=\"download.*?bonus\" id=\"(\\d+)\" >.*?<td class=\"cell\">(.*?)</td><td class=\"cell\">(.*?)</td><td class=\"cell\">(.*?)</td><td class=\"cell\">(.*?)</td>",QRegularExpression::DotMatchesEverythingOption);

    connect(ui->LaunchOtakuLoader,SIGNAL(clicked()),SLOT(LancerOL()));
    connect(this,SIGNAL(afficherTexteLauncher(QString)),this->ui->plainTextEdit,SLOT(appendPlainText(QString)));
    //connect(this,SIGNAL(ajouterAnimeOl(QVector<Anime>)),this->affichage, SLOT(recevoirListeAnime(QVector<Anime>&)));

    //ui->plainTextEdit->setReadOnly(true);
    ui->plainTextEdit->setTextInteractionFlags(Qt::NoTextInteraction);

    QScriptEngine engine;
    QString str;

    // Read the PAC file in a String
    QFile scriptFile("C:\\Users\\segard_d\\AppData\\Roaming\\Juniper Networks\\Network Connect 7.1.7\\instantproxy.pac");
    if ( !scriptFile.open(QIODevice::ReadOnly|QIODevice::Text) ) {
        qDebug() << "Impossible d'ouvrir le fichier pac !" << endl;
    } else {
        qDebug() << "Fichier pac ouvert avec succes !" << endl;
    }
    str = scriptFile.readAll();
    scriptFile.close();

    // Inject the extra JS function as explained above
    QScriptValue dnsResolveFunction = engine.newFunction(ProxyPac::dnsResolve);
    engine.globalObject().setProperty("dnsResolve", dnsResolveFunction);
    QScriptValue isPlainHostNameFunction = engine.newFunction(ProxyPac::isPlainHostName);
    engine.globalObject().setProperty("isPlainHostName", isPlainHostNameFunction);
    QScriptValue isInNetFunction = engine.newFunction(ProxyPac::isInNet);
    engine.globalObject().setProperty("isInNet", isInNetFunction);
    QScriptValue myIpAddressFunction = engine.newFunction(ProxyPac::myIpAddress);
    engine.globalObject().setProperty("myIpAddress", myIpAddressFunction);
    QScriptValue shExpMatch = engine.newFunction(ProxyPac::shExpMatch);
    engine.globalObject().setProperty("shExpMatch", shExpMatch);

    // Version CRADE
    QScriptValue localHostOrDomainIs = engine.newFunction(ProxyPac::localHostOrDomainIs);
    engine.globalObject().setProperty("localHostOrDomainIs", localHostOrDomainIs);
    QScriptValue dnsDomainIs = engine.newFunction(ProxyPac::dnsDomainIs);
    engine.globalObject().setProperty("dnsDomainIs", dnsDomainIs);

    // Evalute the PAC file
    if ( engine.canEvaluate(str) ) {
       engine.evaluate(str);
       QScriptValue ctor = engine.evaluate("FindProxyForURL(\"http://otaku-attitude.net\", \"otaku-attitude.net\")");
       if ( !ctor.isError() ) {
           this->proxy_address = ctor.toString().mid(6);
           qDebug() << proxy_address << endl;
       } else {
           qDebug() << ctor.toString() << endl;
       }
    } else {
        qDebug() << "Impossible d'evaluer..." << endl;
    }

    // ---------- TODO ------------
    // On récupère bien ip + port proxy depuis le .pac stockés dans this->proxy_address
    // sous la forme ip:port
    // il faut passer ip + port à l'objet QNetworkProxy (les deux sont pas liés)
    // ---------- TODO ------------

    // On veut utiliser un proxy http
    //this->proxy.setType(QNetworkProxy::HttpProxy);

    // On n'utilise pas de proxy
    this->proxy.setType(QNetworkProxy::NoProxy);

    // IP + Port du proxy
    //this->proxy.setHostName("ip");
    //this->proxy.setPort(3128);

    // Identification au proxy
    //this->proxy.setUser("toto");
    //this->proxy.setPassword("tutu");
}

Launcher::~Launcher()
{
    delete ui;
}

void Launcher::LancerOL(){

    //this->parsing_liste = new QRegularExpression("\(fiche-anime-\.*?\.html\)\.*?img src=\\\"(\.*?)\\\"\.*?alt=\\\"(\.*?)");
    //this->parsing_liste = new QRegularExpression("(\"fiche-anime-\\.*?\\.html)\"");
    this->affichage = new GuiOL();
    connect(this,SIGNAL(ajouterAnimeOl(Anime *)),this->affichage, SLOT(recevoirListeAnime(Anime *)));
    this->affichage->show();
    //this->hide();

    if(!QDir("data").exists()) {
        QDir().mkdir("data");
        QDir().mkdir("data/img");
        QDir().mkdir("data/fiches");
    }

    this->recupListe();

    QFile* file = new QFile("data/animes.xml");

    if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) {
        emit afficherTexteLauncher(QString("Impossible de lire le fichier xml."));
        return;
    }

    QDomDocument doc("animes");

    if(!doc.setContent(file)) {
        return;
    }

    QDomElement docElem = doc.documentElement();
    QDomNodeList liste_url = docElem.elementsByTagName("fiche");    
    QDomNodeList liste_img = docElem.elementsByTagName("image");

    int i;
    for(i=0; i<liste_url.count(); i++) {
        QDomElement nom_fiche = liste_url.item(i).toElement();
        QDomElement url_img = liste_img.item(i).toElement();
        AnimeTask *task = new AnimeTask(this->proxy, nom_fiche.text(), url_img.text(), this->parsing_anime,this->parsing_anime_infos,this->parsing_episodes,this->parsing_bonus);

        QThreadPool::globalInstance()->start(task,1);
    }

    file->close();
    delete file;

    qDebug() << QString("END;") << endl;

}

void Launcher::recupListe(){
    emit afficherTexteLauncher(QString("Lancement en cours..."));

    QString alphabet("-ABCDEFGHIJKLMNOPQRSTUVWXYZ");

    int i;
    unsigned j;
    int nb_anime = 0;
    int nb_anime_total = 0;

    QDomDocument doc;
    QDomElement root = doc.createElement("animes");

    emit afficherTexteLauncher(QString("Récupération des données. "));
    QString message;
    int scroll;
    bool found;

    QNetworkAccessManager *manager = new QNetworkAccessManager();
    manager->setProxy(this->proxy);


    for(i=0; i<alphabet.length(); i++) {
        scroll = 0;

        do {
            found = false;
            QString currentURL("http://www.otaku-attitude.net/liste-dl-animes.php?lettre=");
            QString currentLettre(alphabet[i]);

            QUrl url = QUrl(currentURL+currentLettre+QString("&scroll=")+QString("%1").arg(scroll));
            QNetworkRequest request(url);

            QNetworkReply *reponse = manager->get(request);
            QEventLoop loop;
            connect(reponse,SIGNAL(finished()),&loop,SLOT(quit()));
            loop.exec();

            nb_anime_total += nb_anime;
            nb_anime = 0;

            string html = reponse->readAll().data();
            delete reponse;

            QRegularExpressionMatchIterator match = this->parsing_liste->globalMatch(QString(html.c_str()));

            while(match.hasNext()){
                found = true;
                QDomElement anime = doc.createElement("anime");
                QDomElement nom = doc.createElement("nom");
                QDomElement image = doc.createElement("image");
                QDomElement fiche = doc.createElement("fiche");

                QRegularExpressionMatch resultat = match.next();

                fiche.appendChild(doc.createTextNode(resultat.captured(1)));
                image.appendChild(doc.createTextNode(resultat.captured(2)));
                nom.appendChild(doc.createCDATASection(resultat.captured(3)));
                QStringList list = image.text().split('/');
                Anime *myanime = new Anime(resultat.captured(3), resultat.captured(1).left(resultat.captured(1).length()-5),list[list.size()-1]);
                emit ajouterAnimeOl(myanime);

                nb_anime++;

                anime.appendChild(nom);
                anime.appendChild(image);
                anime.appendChild(fiche);

                root.appendChild(anime);
            }

            for(j=0; j<message.length()+1; j++) {
                ui->plainTextEdit->textCursor().deletePreviousChar();
            }

            message = QString("%1").arg(i*100/26)+QString("%");
            emit afficherTexteLauncher(message);

            scroll++;
        } while(found);
    }
    delete manager;

    doc.appendChild(root);

    QFile data("data/animes.xml");
    if (data.open(QFile::WriteOnly | QFile::Truncate)) {
        QTextStream out(&data);
        doc.save(out, 4);

        emit afficherTexteLauncher(QString("Écriture du fichier xml..."));
        emit afficherTexteLauncher(QString("%1").arg(nb_anime_total)+QString(" animes"));

        data.close();
    } else {
        emit afficherTexteLauncher(QString("Impossible d'écrire le fichier xml..."));
    }

}
